package com.acme.bankapp.networking.email;

import com.acme.bankapp.domain.client.Client;

import java.util.LinkedList;
import java.util.List;

public class EmailService {
    private EmailQueue queue = new EmailQueue();
    private Thread emailSendingThread;

    private class EmailQueue {
        private List<Email> emailList = new LinkedList<>();

        private final Object monitor = new Object();
        private boolean isInterrupted;

        public void add(Email email) {
            if (!isInterrupted) {
                synchronized (monitor) {
                    emailList.add(email);
                    System.out.println("Email added");
                    monitor.notify();
                }
            }
        }

        public void remove() {
            Email email;
            while (true) {
                synchronized (monitor) {
                    if (emailList.isEmpty()) {
                        if (isInterrupted) {
                            System.out.println(Thread.currentThread().getName() +
                                    ": thread was finished");
                            return;
                        } else {
                            try {
                                System.out.println(Thread.currentThread().getName() +
                                        ": thread is waiting for adding");
                                monitor.wait();
                                continue;
                            } catch (InterruptedException e) {
                                System.out.println(Thread.currentThread().getName() +
                                        ": thread was interrupted in waiting time");
                                isInterrupted = true;
                                continue;
                            }
                        }
                    } else {
                        System.out.println(Thread.currentThread().getName() +
                                ": getting email from queue");
                        email = emailList.remove(0);
                    }
                }
                try {
                    System.out.println(Thread.currentThread().getName() + ": email sent: " + email);
                    // Long time message sending
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    isInterrupted = true;
                }
            }
        }
    }

    public void sendNotificationEmail(final Client client, final String address, final String subject) {
        queue.add(new Email(client, address, subject));
    }

    public EmailService() {
        emailSendingThread = new Thread() {
            @Override
            public void run() {
                queue.remove();
                System.out.println(this.getName() + ": Thread was finished");
            }
        };
    }

    public void startTransmission() {
        emailSendingThread.start();
    }

    public synchronized void close() {
        System.out.println("Interrupt thread");
        emailSendingThread.interrupt();
    }
}
